package world;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Author implements Comparable<Author> {
    private String nome;
    private List<Message> messages;
    private Set<Issue> issues;
    
    public Author(){
        this.messages = new ArrayList<Message>();
        this.issues = new HashSet<Issue>();
    }
    //insere a mensagem na lista de mensagens do autor
    public void insertMessage(Message msg){
        this.messages.add(msg);
    }
    // insere a issue na lista de issues que o autor participou
    public void insertIssue(Issue issue){
        this.issues.add(issue);
    }
    
    //retorna uma mensagem do autor que possui o id especificado
    public Message getMessage(long id){
        for (int i = 0; i < this.messages.size(); i++) {
            if(id == this.messages.get(i).getId()){
                return this.messages.get(i);
            }
        }
        return null;
    }
    
    //retorna uma String com todos os tokens de todas as mensagens do autor 
    public String getTokens() {
        StringBuilder tokens = new StringBuilder();
        for (int i = 0; i < this.messages.size(); i++) {
            tokens.append(this.messages.get(i).getTokens());
            if(i < this.messages.size()-1){
                tokens.append(" ");
            }
        }
        return tokens.toString();
    }
    //retorna uma Lista com todos os tokens de todas as mensagens do autor 
    public List<String> getTokensList() {
        Set<String> tokensSet = new HashSet<String>();
        for (int i = 0; i < this.messages.size(); i++) {
            String tokens = this.messages.get(i).getTokens();
            tokensSet.addAll(Arrays.asList(tokens.split(" ")));
        }
        return Arrays.asList(tokensSet.toArray(new String[0]));
    }
    
      // dado o mundo retorna o vetor de incidência de 0 e 1 dos tokens das mensagens do autor
    public int[] getVector(List<String> world){
        int[] vector = new int[world.size()];
        List<String> tokens = this.getTokensList();
        for (int i = 0; i < tokens.size(); i++) {
            int posicao = Collections.binarySearch(world, tokens.get(i));
            // como o mundo foi restringido por data podem haver tokens aqui
                // que nao existem no mundo
                if (posicao >= 0) {
                    vector[posicao] = 1;
                }
        }
        //String vectorString = Arrays.toString(vector).replaceAll("[\\[|\\]]", "");
        return vector;
    }
    
    //verifica se o autor participou de uma determinada issue
    public boolean containsIssue(Issue issue){
        return this.issues.contains(issue);
    }
    
    //retorna a data da primeira participacao;
    public java.sql.Timestamp getInitialPaticipation(){
        java.sql.Timestamp min = this.messages.get(0).getData();
        for (int i = 1; i < this.messages.size(); i++) {
            java.sql.Timestamp data = this.messages.get(i).getData();
            if(min.compareTo(data) > 0){
                min = data;
            }
        }
        return min;
    }

    //retorna a data da ultima participacao;
    public java.sql.Timestamp getFinalPaticipation(){
        java.sql.Timestamp max = this.messages.get(0).getData();
        for (int i = 1; i < this.messages.size(); i++) {
            java.sql.Timestamp data = this.messages.get(i).getData();
            if(max.compareTo(data) < 0){
                max = data;
            }
        }
        return max;
    }

    /*
     * GETS E SETS                  
     */
    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }
    
    public String toString(){
        return this.getNome();
    }
    
    @Override
    public int compareTo(Author other) {
        return this.nome.compareToIgnoreCase(other.getNome());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Author other = (Author) obj;
        if ((this.nome == null) ? (other.nome != null) : !this.nome.equals(other.nome)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 89 * hash + (this.nome != null ? this.nome.hashCode() : 0);
        return hash;
    }
}
